/**
 * 
 */
package com.eagle.coders.server.db;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.persistence.Table;
import javax.sql.DataSource;

import org.postgresql.Driver;

import com.eagle.coders.server.db.annotation.Jdbc;

/**
 * @author Anees
 * 
 */
@Jdbc
public class JdbcDbDaoImpl implements DatabaseDao {

	private Connection connection;

	private ResultSet resultSet;

	private PreparedStatement pstmt;

	private Map<String, Integer> entityPositionMap = new HashMap<String, Integer>();

	public JdbcDbDaoImpl() {

		init();
	}

	private void init() {
		try {
			
			new Driver();
			Context ctx = new InitialContext();
			DataSource ds = (DataSource) ctx.lookup("jdbc/PostgresDS");
			connection = ds.getConnection();
		} catch (Exception e) {
			connection = null;
		}
	}

	private void createPreparedStatement(final String tableName,
			final Map<String, Object> conditions) {

		StringBuffer queryBuff = new StringBuffer();
		
		queryBuff.append("select ");
		Set<String> fieldSet = conditions.keySet();
		for (String field : fieldSet) {
			queryBuff.append(field + " ");
		}

		queryBuff.append(" from " + tableName + " o where ");

		int i = 1;
		for (String field : fieldSet) {
			queryBuff.append(" o." + field + "= ? ");
			entityPositionMap.put(field, i);
			i++;
		}
		try {
			pstmt = connection.prepareStatement(queryBuff.toString());
		} catch (Exception e) {
			pstmt = null;
		}
	}
	
	/**
	 * 
	 * @return
	 * @throws SQLException
	 */
	private Map<String, Object> findFromResultSet() throws SQLException {
		
		Map<String, Object> resultObjectMap = new HashMap<String, Object>();
		Set<String> fields = entityPositionMap.keySet();
		for(String field : fields){
			
			resultObjectMap.put(field, resultSet.getObject(field));
		}
		return resultObjectMap;
	}

//	/**
//	 * 
//	 */
//	@Override
//	public Map<String, Object> findByCondition(String tableName,
//			Map<String, Object> conditions) {
//
//		createPreparedStatement(tableName, conditions);
//		Set<String> fields = entityPositionMap.keySet();
//		for (String field : fields) {
//			Integer position = entityPositionMap.get(field);
//			if (conditions.containsKey(field)) {
//				String value = conditions.get(field).toString();
//				try {
//					pstmt.setString(position, value);
//				} catch (Exception e) {
//					// TODO: I will thorw exception on later stages
//					e.printStackTrace();
//				}
//			}
//		}
//		
//		try{
//			resultSet = pstmt.executeQuery();
//			return findFromResultSet();
//			
//		}catch(Exception e){
////			TODO: need to rethrow the Exception : i will do it latter
//			
//			return null;
//		}
//	}

//	@Override
//	public List<?> findByAll(String tableName) {
//		// TODO Auto-generated method stub
//		return null;
//	}

	private void close() {

		try {
			if (!pstmt.isClosed())
				pstmt.close();

			if (!resultSet.isClosed())
				resultSet.close();

			if (!connection.isClosed())
				connection.close();

		} catch (Exception e) {
			pstmt = null;

			resultSet = null;

			connection = null;
		}
	}

	@Override
	public <T> List<T> findByAllMapper(Class<T> mapperClz) {
		String tableName = "";

		if(mapperClz.isAnnotationPresent(Table.class)){
			Table table = mapperClz.getAnnotation(Table.class);
			tableName = table.name();
		}
		
		String query = "SELECT * FROM "+tableName;
		
		try{
			
			pstmt = connection.prepareStatement(query);
			
			resultSet = pstmt.executeQuery();
			
			Map<String, Object> value = findFromResultSet();
			
		}catch(Exception e){
			pstmt = null;
		}
		return null;
	}


	@Override
	public <T> T findMapper(Class<T> mapperClz) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public <T> List<T> findByConditionForMapper(Class<T> mapperClz,
			Map<String, Object> condition) {
		// TODO Auto-generated method stub
		return null;
	}
}
